﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows;
using System.Data;
using System.Windows.Input;
using DSPL.Contracts.Interfaces;
using Microsoft.Practices.Unity;
using DSPL.Common.ViewModel;

namespace DSPL.Common.CommonControls.Controls
{
    /// <summary>
    /// Autor: Thushari
    /// To have the common text box to display master data.
    /// </summary>

    public class TempObject
    {
        public string ClsStkAcc { get; set; }
        public string PurAcc { get; set; }
        public string PurRetAcc { get; set; }

    }

    public class TxtMasterData : TextBox
    {
        #region private variables
        private string _cFilter = string.Empty;
        private string _oFields = string.Empty;
        private string _cHelp = string.Empty;
        private bool _isMandatory = false;
        private bool _isEnabledHelp = true;
        protected string _selectTable = string.Empty;
        private string _keyField = string.Empty;
        private int _helpSearch = 0;
        private string _helpSearchText = string.Empty;
        private string _selectQuery = string.Empty;
        private string _selectedValue = string.Empty;
        private string _primaryKeyField = string.Empty;
        private Dictionary<string, object> _bindObjects;
        private List<string> _fieldList;
        private bool _isDorpFilter;
        private bool _lValidate = false;
        private bool _lDropWhere = false;
        protected ILoadHelp _masterLoadHelp;
        protected IMasterDataRetrieve _masterDataService;
        protected IReadService _masterReadService;
        protected IMessageService _messageService;
        private bool isUpdatedFromTextChange;
        private bool isUpdatedFromIdChange;

        #endregion

        #region Properties

        public string cFilter
        {
            get { return _cFilter; }
            set
            {
                if (_cFilter != null)
                    _cFilter = value;
            }
        }

        public string oFields
        {
            get { return _oFields; }
            set
            {
                if (value != null)
                    _oFields = value;
            }
        }

        public string HelpCode
        {
            get { return _cHelp; }
            set
            {
                if (_cHelp != null)
                    _cHelp = value;
            }
        }

        public bool IsMandatory
        {
            get { return _isMandatory; }
            set
            {
                _isMandatory = value;
            }
        }

        public bool IsEnabledHelp
        {
            get { return _isEnabledHelp; }
            set
            {
                _isEnabledHelp = value;
            }
        }

        public string SelectTable
        {
            get { return _selectTable; }
            set
            {
                if (_selectTable != null)
                    _selectTable = value;
            }
        }

        public string KeyField
        {
            get { return _keyField; }
            set
            {
                if (_keyField != null)
                    _keyField = value;
            }
        }

        public string PrimaryKeyField
        {
            get { return _primaryKeyField; }
            set
            {
                if (_primaryKeyField != null)
                    _primaryKeyField = value;
            }

        }
        public string HelpSearchText
        {
            get { return _helpSearchText; }
            set
            {
                if (_helpSearchText != null)
                    _helpSearchText = value;
            }
        }

        public int HelpSearch
        {
            get { return _helpSearch; }
            set
            {
                _helpSearch = value;
            }
        }

        public string SelectedValue
        {
            get { return _selectedValue; }
            set
            {
                if (_selectedValue != null)
                    _selectedValue = value;
            }
        }


        public Dictionary<string, string> BindControls
        {
            get { return ((Dictionary<string, string>)GetValue(BindControlsProperty)); }
            set { SetValue(BindControlsProperty, value); }
        }

        public Dictionary<string, object> BindObjects
        {
            get { return _bindObjects; }
            set { _bindObjects = value; }
        }

        // Help screen field list
        public List<string> FieldList
        {
            get { return _fieldList; }
            set { _fieldList = value; }
        }


        public bool IsDropFilter
        {
            get { return _isDorpFilter; }
            set { _isDorpFilter = value; }
        }

        public bool IsDropWhere
        {
            get { return _lDropWhere; }
            set { _lDropWhere = value; }
        }

        public bool IsValidate
        {
            get { return _lValidate; }
            set { _lValidate = value; }
        }

        public object MasterUnityContainer
        {
            get
            {
                return ((object)GetValue(MasterUnityContainerProperty));
            }
            set
            {
                SetValue(MasterUnityContainerProperty, value);

            }
        }

        public object MasterCodeValue
        {
            get
            {
                return (object)GetValue(CodeValueProperty);
            }
            set
            {
                SetValue(CodeValueProperty, value);
             


            }
        }

        public int MasterKeyValue
        {
            get
            {
                return ((int)GetValue(KeyValueProperty));
            }
            set
            {
                SetValue(KeyValueProperty, value);

            }
        }

        #endregion

        #region Dependency Properties

        public static readonly DependencyProperty BindControlsProperty = DependencyProperty.Register("BindControls", typeof(Dictionary<string, string>), typeof(TxtMasterData), new PropertyMetadata());
        public static readonly DependencyProperty MasterUnityContainerProperty = DependencyProperty.Register("MasterUnityContainer", typeof(object), typeof(TxtMasterData), new PropertyMetadata());
        public static readonly DependencyProperty CodeValueProperty = DependencyProperty.Register("MasterCodeValue", typeof(object), typeof(TxtMasterData), new PropertyMetadata("", new PropertyChangedCallback(CodeChangedCallBack)));
        public static readonly DependencyProperty KeyValueProperty = DependencyProperty.Register("MasterKeyValue", typeof(System.Int32), typeof(TxtMasterData), new PropertyMetadata(0, new PropertyChangedCallback(KeyChangedCallBack)), new ValidateValueCallback(ValidateKeyValue));

        private static void KeyChangedCallBack(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
        {
            TxtMasterData objTextBox = depObj as TxtMasterData;

            if (!objTextBox.isUpdatedFromTextChange)
            {
                objTextBox.ResolveDependencies();
                objTextBox.isUpdatedFromIdChange = true;
                objTextBox.MasterCodeValue = objTextBox._masterReadService.GetUniqueCodeValue(objTextBox.SelectTable, objTextBox.PrimaryKeyField, objTextBox.MasterKeyValue.ToString(), objTextBox.KeyField);
                // objTextBox.MasterKeyValue = objTextBox._masterReadService.GetPrimaryKeyValue(objTextBox.SelectTable, objTextBox.KeyField, objTextBox.MasterCodeValue.ToString(), objTextBox.PrimaryKeyField);
                //objTextBox.MasterCodeValue = "";         
               
            }

            objTextBox.isUpdatedFromTextChange = false;
        }

        private static void CodeChangedCallBack(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
        {
             TxtMasterData objTextBox = depObj as TxtMasterData;

            if (!objTextBox.isUpdatedFromIdChange)
            {
                objTextBox.ResolveDependencies();
                objTextBox.isUpdatedFromTextChange = true;
                objTextBox.MasterKeyValue = objTextBox._masterReadService.GetPrimaryKeyValue(objTextBox.SelectTable, objTextBox.KeyField, objTextBox.MasterCodeValue.ToString(), objTextBox.PrimaryKeyField);
            }

            objTextBox.isUpdatedFromIdChange = false;
        }


        #endregion
        #region Constructor



        #endregion


        #region Events

        #region Double click event


        protected override void OnMouseDoubleClick(System.Windows.Input.MouseButtonEventArgs e)
        {
            base.OnMouseDoubleClick(e);

            if ((this.IsEnabled == true) && (_isEnabledHelp))
            {
                DisplaySearchForm();

                if (this.IsValidate && !this.Text.Equals(this.SelectedValue))
                {
                    this.LinkObjectRefresh();
                }
            }
            this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));

        }
        #endregion

        #region Got Focus event
        protected override void OnGotFocus(System.Windows.RoutedEventArgs e)
        {
            base.OnGotFocus(e);

            switch (this.Text.GetType().ToString())
            {
                case "System.Int32":
                    this.SelectedValue = Convert.ToString(this.Text);
                    break;
                case "System.DateTime":
                    this.SelectedValue = Convert.ToString(this.Text);
                    break;

                default:
                    this.SelectedValue = this.Text;
                    break;
            }
        }

        #endregion

        #region Key press event



        protected override void OnKeyDown(System.Windows.Input.KeyEventArgs e)
        {
            base.OnKeyDown(e);

            if ((e.Key == Key.F1) && (_isEnabledHelp))
            {

                DisplaySearchForm();
                if (this.IsValidate && !this.Text.Equals(this.SelectedValue))
                {
                    this.LinkObjectRefresh();
                }
                this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
            }


        }

        #endregion

        #region Lost Focus event

        protected override void OnLostFocus(RoutedEventArgs e)
        {
            base.OnLostFocus(e);
            if (this.IsValidate && !this.Text.Equals(this.SelectedValue))
            {
                this.LinkObjectRefresh();

            }
        }

        #endregion



        #endregion

       

        #region methods
        #region Build the filter

        public virtual string GetFilter()
        {
            string cFilter = string.Empty, cStrbal, cNewFilter, cPartOfExp, cWhere = string.Empty;
            int nOccurPlus, nEndPosition, nStrLen, nOccurDoubleQuote = 0, nOccursingleQuote = 0;
            bool isFirstSingleQuote, isFirstDoubleQuote = false;

            if (this.oFields != string.Empty)
            {
                string cControlList = this.oFields;
                List<string> controlList = this.oFields.Split(',').ToList();

                foreach (string controlName in controlList)
                {
                    if (FindName(controlName) != null)
                    {
                        cFilter = cFilter + ((TextBox)FindName(controlName)).Text == string.Empty ? "" : (cFilter != string.Empty ? " AND " : "") + ((TextBox)FindName(controlName)).Tag.ToString() + "='" + ((TextBox)FindName(controlName)).Text.Trim() + "'";
                    }
                }

                if (this.IsDropFilter)
                {

                }
                cWhere = cWhere + (cWhere == string.Empty ? "" : " AND ") + cFilter;
            }

            if (this.cFilter != string.Empty)
            {
                cFilter = this.cFilter.Trim();
                isFirstSingleQuote = (cFilter.Substring(0, 1) == "'" ? true : false);
                isFirstDoubleQuote = (cFilter.Substring(0, 1) == "\"" ? true : false);
                if (isFirstSingleQuote || isFirstDoubleQuote)
                {
                    nOccurPlus = cFilter.Length - cFilter.Replace("+", "").Length;
                    cStrbal = cFilter;
                    cNewFilter = "";
                    for (int i = 1; i <= nOccurPlus + 1; i++)
                    {
                        nStrLen = cStrbal.Length;
                        nEndPosition = (cStrbal.IndexOf("+") == -1 ? nStrLen : cStrbal.IndexOf("+"));
                        cPartOfExp = cStrbal.Substring(0, nEndPosition);
                        nOccursingleQuote = cPartOfExp.Length - cPartOfExp.Replace("'", "").Length;
                        nOccurDoubleQuote = cPartOfExp.Length - cPartOfExp.Replace("\"", "").Length;

                        if ((isFirstSingleQuote) && (nOccursingleQuote >= 2))
                        {
                            // replace the first and last occurenace of single quote.
                            int OccuranceIndex = cPartOfExp.IndexOf("'");
                            cPartOfExp = cPartOfExp.Remove(OccuranceIndex, 1).Insert(OccuranceIndex, "");
                            OccuranceIndex = cPartOfExp.LastIndexOf("'");
                            cPartOfExp = cPartOfExp.Remove(OccuranceIndex, 1).Insert(OccuranceIndex, "");
                        }

                        if ((isFirstDoubleQuote) && (nOccurDoubleQuote >= 2))
                        {
                            // replace the first and last occurenace of double quote.
                            int OccuranceIndex = cPartOfExp.IndexOf("\"");
                            cPartOfExp = cPartOfExp.Remove(OccuranceIndex, 1).Insert(OccuranceIndex, "");
                            OccuranceIndex = cPartOfExp.LastIndexOf("\"");
                            cPartOfExp = cPartOfExp.Remove(OccuranceIndex, 1).Insert(OccuranceIndex, "");
                        }

                        cNewFilter = cNewFilter + cPartOfExp;

                        if (nEndPosition != nStrLen)
                        {
                            cStrbal = cStrbal.Substring(nEndPosition + 1, nStrLen);
                            nEndPosition = cStrbal.IndexOf("+");
                            cNewFilter = cNewFilter + cStrbal.Substring(1, nEndPosition);
                            cStrbal = cStrbal.Substring(nEndPosition + 1, nStrLen);
                        }
                    }
                    cFilter = cNewFilter;
                    cWhere = cWhere + (cWhere != string.Empty ? " AND " : "") + cFilter;
                }
                else
                {
                    cWhere = cWhere + (cWhere != string.Empty ? " AND " : "") + cFilter;
                }
            }

            return cWhere;
        }
        #endregion


        #endregion

        private static bool ValidateKeyValue(object obj)
        {
            if (obj != null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public void LinkObjectRefresh()
        {

            string cInputCode, fieldsList, cWhere, cSelFrom, cWhereGet;
            string sourceTable;
            string fieldListProperties = string.Empty;
            fieldsList = cWhereGet = string.Empty;
            string sqlStatement;
            if (this.Text != string.Empty)
            {
                cInputCode = this.Text;
                fieldsList = GetFieldListControls(BindControls);
                if (_bindObjects != null)
                {
                    fieldListProperties = GetFieldListProperties(_bindObjects);
                    fieldListProperties = fieldListProperties.Substring(0, fieldListProperties.Length - 1);
                }
                fieldsList = fieldsList + (fieldsList != string.Empty && fieldListProperties != string.Empty ? "," : "") + fieldListProperties;
                if (this.IsDropWhere)
                {
                    cWhereGet = this.GetFilter();
                }
                cWhere = (this.KeyField).Trim() + "='" + cInputCode + "'" + ((cWhereGet == string.Empty) ? "" : " && " + cWhereGet);
                sourceTable = (this.SelectTable).Trim();
                sqlStatement = "SELECT " + fieldsList + " FROM " + sourceTable + ((cWhere == string.Empty) ? "" : " WHERE " + cWhere);
                DataTable dtMasterData = GetMasterData(sqlStatement);

                if (dtMasterData.Rows.Count > 0)
                {
                    PopulateBindControls(dtMasterData.Rows[0], BindControls);
                    if (BindObjects != null)
                    {
                        PopulateBindObjects(dtMasterData.Rows[0], BindObjects);
                    }
                    this.Background = Brushes.White;
                }
                else
                {
                    if (this.IsMandatory)
                    {
                        this.Background = Brushes.LavenderBlush;

                    }
                    this.Text = "";
                    PopulateBindControls(null, BindControls, false);
                    if (BindObjects != null)
                    {
                        PopulateBindObjects(null, BindObjects);
                    }
                }
            }
            else
            {
                if (this.IsMandatory)
                {
                    this.Background = Brushes.LavenderBlush;
                }
                else
                {
                    this.Background = Brushes.White;
                }

                cSelFrom = (this.SelectTable).Trim();
                PopulateBindControls(null, BindControls, false);
                if (BindObjects != null)
                {
                    PopulateBindObjects(null, BindObjects);
                }
            }
        }

        /// <summary>
        /// To display search form
        /// </summary>
        private void DisplaySearchForm()
        {
            ResolveDependencies();
            if (_masterLoadHelp != null)
            {
                _masterLoadHelp.DisplayHelpForm -= DisplayData;
                _masterLoadHelp.DisplayHelpForm += DisplayData;
                _masterLoadHelp.GetHelp(HelpCode);
            }
        }

        /// <summary>
        /// To load the search form with the filtered data.
        /// </summary>
        /// <param name="dtData"></param>
        private void DisplayData(DataTable dtData)
        {

            ListWindowViewModel vmListWindow = new ListWindowViewModel();
            if (vmListWindow != null)
            {
                vmListWindow.DtDatGridData = dtData;
                vmListWindow.Initialize();
                _messageService.ShowPopupWindow(vmListWindow);
                if (vmListWindow.SelectedRow != null)
                {
                    this.Text = vmListWindow.SelectedRow[KeyField].ToString().Trim();
                }
            }


            //  var frmSerachObj = new Search(dtData, (IUnityContainer)MasterUnityContainer);
            //frmSerachObj.SendSelectedToMaster -= DisplaySelectedCode;
            //frmSerachObj.SendSelectedToMaster += DisplaySelectedCode;
            //frmSerachObj.ShowDialog();

        }

        private void DisplaySelectedCode(string id)
        {
            this.Text = id;

        }

        private DataTable GetMasterData(string query)
        {
            ResolveDependencies();
            return _masterDataService.GetMasterData(query);

        }

        private void PopulateBindObjects(DataRow masterData, Dictionary<string, object> bindObjects)
        {
            if (bindObjects != null && masterData != null)
            {
                foreach (KeyValuePair<string, object> kvp in bindObjects)
                {

                    TempObject c = (TempObject)kvp.Value;
                    typeof(TempObject).GetProperty(kvp.Key.ToString()).SetValue(c, masterData[kvp.Key.ToString()].ToString(), null);

                }
            }
        }

        private void PopulateBindControls(DataRow masterData, Dictionary<string, string> bindControls, bool isFound = true)
        {
            if (bindControls != null)
            {
            
            var parentWindow = Window.GetWindow(this);
            
            ContentControl contetn = (ContentControl)parentWindow.FindName("popupContent");

            DependencyObject contentPresenter = VisualTreeHelper.GetChild(contetn, 0);

            UserControl userControl = VisualTreeHelper.GetChild(contentPresenter, 0) as UserControl;
                      
            foreach (KeyValuePair<string, string> kvp in bindControls)
                {
                    string value = (isFound ? masterData[kvp.Key.ToString()].ToString() : "");
                    var uie = (Visual)userControl.FindName(kvp.Value);
                    if (uie.GetType() == typeof(TextBox))
                    {
                        ((TextBox)uie).Text = value;
                    }
                    else if (uie.GetType() == typeof(TxtMasterData))
                    {
                        ((TxtMasterData)uie).Text = value;
                    }

                    else if (uie.GetType() == typeof(TxtCurCode))
                    {
                        ((TxtCurCode)uie).Text = value;
                    }

                    else if (uie.GetType() == typeof(TxtCurRate))
                    {
                        ((TxtCurRate)uie).Text = value;
                    }

                }
            }
        }

        private string GetFieldListControls(Dictionary<string, string> bindControls)
        {
            string fieldList = string.Empty;

            if (bindControls == null)
            {
                return "*";
            }
            foreach (KeyValuePair<string, string> kvp in bindControls)
            {

                fieldList = fieldList + kvp.Key.ToString();
            }

            return fieldList;
        }

        private string GetFieldListProperties(Dictionary<string, object> bindObjects)
        {
            string fieldList = string.Empty;

            if (bindObjects != null)
            {
                foreach (KeyValuePair<string, object> kvp in bindObjects)
                {

                    fieldList = fieldList + kvp.Key.ToString() + ",";
                }
            }
            return fieldList;
        }

        protected virtual void ResolveDependencies()
        {
            if (MasterUnityContainer != null)
            {
                IUnityContainer masterUnityContainer = (IUnityContainer)MasterUnityContainer;
                if (_masterLoadHelp == null)
                {
                    _masterLoadHelp = masterUnityContainer.Resolve<ILoadHelp>();
                }

                if (_masterDataService == null)
                {
                    _masterDataService = masterUnityContainer.Resolve<IMasterDataRetrieve>();
                }


                if (_messageService == null)
                {
                    _messageService = masterUnityContainer.Resolve<IMessageService>();
                }

                if (_masterReadService == null)
                {
                    _masterReadService = masterUnityContainer.Resolve<IReadService>();
                }
            }
        }

        private static void GetKeyValue()
        {

        }

    }


}
